package ai.platon.pulsar.agentic.ai.tta

import ai.platon.pulsar.browser.driver.chrome.dom.model.BrowserUseState
import ai.platon.pulsar.common.config.ImmutableConfig
import ai.platon.pulsar.external.ModelResponse
import ai.platon.pulsar.external.ResponseState
import ai.platon.pulsar.agentic.ActionDescription
import ai.platon.pulsar.agentic.AgentState
import org.junit.jupiter.api.Assertions.*
import org.junit.jupiter.api.Test

private class TestableTextToAction(conf: ImmutableConfig): TextToAction(conf) {
    val agentState = AgentState(1, "", BrowserUseState.DUMMY)
    fun parse(response: ModelResponse): ActionDescription = modelResponseToActionDescription("", agentState, response)
}

class TextToActionParsingTest {

    private val tta = TestableTextToAction(ImmutableConfig())

    @Test
    fun `elements JSON with click builds ToolCall with selector as arg0`() {
        val json = """
            {
              "elements": [
                {
                  "locator": "0,19",
                  "description": "Submit button",
                  "domain": "driver",
                  "method": "click",
                  "arguments": [{"name": "selector", "value": "#submit"}]
                }
              ]
            }
        """.trimIndent()
        val resp = ModelResponse(json, ResponseState.STOP)

        val ad = tta.parse(resp)
        assertNotNull(ad.toolCall)
        assertEquals("driver", ad.toolCall!!.domain)
        assertEquals("click", ad.toolCall!!.method)
        assertEquals("#submit", ad.toolCall!!.arguments["selector"])
        assertFalse(ad.isComplete)
        assertNull(ad.summary)
    }

    @Test
    fun `elements JSON with type maps locator to arg0 and text to arg1`() {
        val json = """
            {
              "elements": [
                {
                  "locator": "#q",
                  "description": "Search input",
                  "domain": "driver",
                  "method": "type",
                  "arguments": [ { "name": "text", "value": "hello" } ]
                }
              ]
            }
        """.trimIndent()
        val resp = ModelResponse(json, ResponseState.STOP)

        val ad = tta.parse(resp)

        val tc = requireNotNull(ad.toolCall)
        assertEquals("driver", tc.domain)
        assertEquals("type", tc.method)
        assertEquals("hello", tc.arguments["text"]) // named mapping for argument values

        assertFalse(ad.isComplete)
    }

    @Test
    fun `plain driver expression fallback is preserved`() {
        val text = """
            driver.click("#ok")
            // some commentary from model
            driver.scrollToMiddle(0.5)
        """.trimIndent()
        val resp = ModelResponse(text, ResponseState.STOP)

        val ad = tta.parse(resp)
        // Should extract driver.* lines only
        assertTrue(ad.toolCall == null || ad.cssFriendlyExpression != null)
//        assertTrue(ad.cssFriendlyExpressions.any { it.startsWith("driver.click(") })
//        assertTrue(ad.cssFriendlyExpressions.any { it.startsWith("driver.scrollToMiddle(") })
        assertFalse(ad.isComplete)
    }
}
